// 命令行依赖
package xconsole

import (
	"errors"
	"sort"
	"strings"
	"sync"
)

var _version = "v1.0.0"

// 定义命令所需要的执行函数结构
type XconsoleInfo func() error

// 定义MAP中所支持的map结构
type Routers struct {
	Name string       `json:"name" form:"name" xml:"name"` // 命令名称
	Desc string       `json:"desc" form:"desc" xml:"desc"` // 命令简介
	App  XconsoleInfo `json:"-" form:"-" xml:"-"`          // 命令执行程序
}

type Apps []Routers

// 实现排序接口sort.Interface中的列表长度
func (s Apps) Len() int { return len(s) }

// 实现排序接口sort.Interface中的i、j交换
func (s Apps) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

// 实现排序接口sort.Interface中的i、j比较，正/顺序 i<j，倒/逆序 i>j
func (s Apps) Less(i, j int) bool { return strings.Compare(s[i].Name, s[j].Name) < 0 }

// 支持的命令分组
// 无前缀分组的直接使用 0000 进行存储
var _default map[string]Apps = map[string]Apps{}
var _default_group []string = []string{}
var slock sync.RWMutex

// 推入命令标识
//
//	name	命令名称
//	desc	命令简介
//	app		命令本地
func Push(name, desc string, app XconsoleInfo) error {
	return Pushs(&Routers{
		Name: name,
		Desc: desc,
		App:  app,
	})
}

// 推入命令标识【以结构体形式推入】
//
//	s	推送的命令结构体
func Pushs(s *Routers) error {
	if s == nil {
		return nil
	}
	slock.Lock()
	defer slock.Unlock()
	s.Name = name_rep(s.Name)
	// 获取命令分组
	groups := splits(s.Name)
	// 判断分组是否存在
	if in_string(groups, _default_group) {
		// 判断命令是否存在
		for i := 0; i < len(_default[groups]); i++ {
			if _default[groups][i].Name == s.Name {
				return errors.New("命令已存在")
			}
		}
		_default[groups] = append(_default[groups], *s)
	} else {
		_default[groups] = Apps{*s}
		_default_group = append(_default_group, groups)
		// 分组排序
		sort.Sort(sort.StringSlice(_default_group))
	}
	// 针对分组中的数据进行排序
	sort.Sort(_default[groups])
	return nil
}

// 移除命令列表
//
//	name	待移除的命令列表
func UnPushs(name []string) error {
	for i := 0; i < len(name); i++ {
		for g := 0; g < len(_default_group); g++ {
			for a := 0; a < len(_default[_default_group[g]]); a++ {
				if _default[_default_group[g]][a].Name == name[i] {
					_default[_default_group[g]] = append(_default[_default_group[g]][:a], _default[_default_group[g]][a+1:]...)
				}
			}
		}
	}
	return nil
}

// 添加h监听等
func init() {
	Push("h", "帮助信息", help)
	Push("help", "帮助信息", help)
	Push("v", "版本信息", version)
	Push("version", "版本信息", version)
}
